package blue.http.internal.core.handler.exception;

import blue.base.core.common.ErrorCodeException;
import blue.http.core.exception.HttpServerException;
import blue.http.internal.core.handler.HandlerResponse;
import com.alibaba.fastjson.JSONException;
import jakarta.validation.ValidationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Jin Zheng
 * @since 2020-01-11
 */
public class ExceptionDispatcher {
	private static Logger logger = LoggerFactory.getLogger(ExceptionDispatcher.class);
	private Map<Class<?>, ExceptionHandler> exceptionHandlerMap = new HashMap<>();
	private ExceptionHandler defaultHandler = new DefaultExceptionHandler();

	public ExceptionDispatcher() {
		this.exceptionHandlerMap.put(ValidationException.class, new ValidationExceptionHandler());
		this.exceptionHandlerMap.put(JSONException.class, new JSONExceptionHandler());
		this.exceptionHandlerMap.put(HttpServerException.class, new HttpServerExceptionHandler());
		this.exceptionHandlerMap.put(ErrorCodeException.class, new ErrorCodeExceptionHandler());
	}

	public void handleException(HandlerResponse response) {
		Throwable cause = response.getCause();
		ExceptionHandler handler = exceptionHandlerMap.get(cause.getClass());
		if (handler != null) {
			handler.handle(response);
			return;
		}
		for (var entry : exceptionHandlerMap.entrySet()) {
			ExceptionHandler exHandler = entry.getValue();
			if (exHandler.accepted(cause)) {
				exHandler.handle(response);
				return;
			}
		}
		logger.debug("Unknown exception handler, uses DefaultExceptionHandler");
		defaultHandler.handle(response);
	}

}
